package com.yonyou.pmclouds.productactive.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.conf.WorkbenchDataSourceProperties;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.ConcurrentOperationException;
import com.yonyou.pmclouds.basecom.lock.AutoReleaseLockUtil;
import com.yonyou.pmclouds.productactive.entity.*;
import com.yonyou.pmclouds.productactive.mapper.BuziJobUpdateLogMapper;
import com.yonyou.pmclouds.productactive.mapper.BuziOrderInfoMapper;
import com.yonyou.pmclouds.productactive.mapper.ProductActiveLogMapper;
import com.yonyou.pmclouds.productactive.process.PrintInitProcess;
import com.yonyou.pmclouds.productactive.process.ScriptProcess;
import com.yonyou.pmclouds.productactive.rmiitf.ProductActiveRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = ProductActiveRemoteService.class)
public class ProductActiveRemoteServiceImpl implements ProductActiveRemoteService {

    @Autowired
    private WorkbenchDataSourceProperties properties;
    @Autowired
    private ProductActiveLogMapper activeMapper;
    @Autowired
    private BuziOrderInfoMapper buziOrderInfoMapper;

    @Autowired
    private BuziJobUpdateLogMapper jobUpdateLogMapper;

    private ObjectMapper mapper = new ObjectMapper();

    @Override
    public void insertLastUpdateLicenseInfo(Date date, String info) {
        //  添加上次更新授权控制信息的时间
        BuziJobUpdateLogVO buziJobUpdateLogVO = new BuziJobUpdateLogVO();
        buziJobUpdateLogVO.setInfo(info);
        buziJobUpdateLogVO.setLastUpdate(date);
        buziJobUpdateLogVO.setPkBuziUpdate(UUID.randomUUID().toString());
        buziJobUpdateLogVO.setChangeFlag(UUID.randomUUID().toString());
        jobUpdateLogMapper.insert(buziJobUpdateLogVO);
    }

    @Override
    public void businessProduct(ProductBusinessRequestVO productbusinessRequestVO) throws BusinessException {
        try {
            ProductActiveLogVO logVO = new ProductActiveLogVO();
            logVO.setLogContent(mapper.writeValueAsString(productbusinessRequestVO));
            logVO.setActiveId(productbusinessRequestVO.getOrderId());
            logVO.setPkActiveLog(UUID.randomUUID().toString());
            activeMapper.insert(logVO);
        } catch (JsonProcessingException e) {
            log.error("产品创建订单错误");
            throw new BusinessException(e.getMessage(), e);
        }
    }

    @Override
    public ProductActiveLogVO saveProductActive(ProductInitRequestVO productInitRequestVO, ActiveInfoVO[] infos, Date activeDate) throws BusinessException {
        boolean lock = AutoReleaseLockUtil.addAutoReleaseLock(productInitRequestVO.getRealUserObject().getActivationCode());
        if (!lock) {
            throw new ConcurrentOperationException("激活正在处理中，请稍后");
        }
        ProductActiveLogVO logVO = new ProductActiveLogVO();
        logVO.setActiveId(productInitRequestVO.getRealUserObject().getActivationCode());
        logVO.setStep(1);
        logVO.setActiveDate(activeDate);
        try {
            // save step info
            logVO.setLogContent(mapper.writeValueAsString(productInitRequestVO));
            logVO.setChangeFlag(UUID.randomUUID().toString());
            activeMapper.insert(logVO);
            String tenantId = productInitRequestVO.getRealUserObject().getTenantId();
            int count = buziOrderInfoMapper.countOfTenant(tenantId);
            // save 订单信息
            BuziOrderInfoVO[] buziInfos = new BuziOrderInfoVO[infos.length];
            for (int i = 0; i < infos.length; i++) {
                buziInfos[i] = new BuziOrderInfoVO();
                buziInfos[i].setPkTenant(tenantId);
                buziInfos[i].setAccountQuantity(infos[i].getAccountQuantity());
                buziInfos[i].setLease(infos[i].getLease());
                buziInfos[i].setOrderCId(infos[i].getOrderCId());
                buziInfos[i].setProductId(infos[i].getProductId());
                buziInfos[i].setSkuId(infos[i].getSkuId());
                buziInfos[i].setChangeFlag(UUID.randomUUID().toString());
                buziInfos[i].setActiveDate(activeDate);
            }
            buziOrderInfoMapper.batchInsert(Arrays.asList(buziInfos));
            if (count <= 0) {
                ScriptProcess process = new ScriptProcess(properties);
                process.executeScript(tenantId, ApplicationConsts.APPLICATION_ID);
                //初始化一套业务对象和打印模版
                PrintInitProcess printInitProcess = new PrintInitProcess(tenantId);
                printInitProcess.initTenantBizz();
            } else {
                log.info("租户{}无需初始化", tenantId);
            }
        } catch (JsonProcessingException e) {
            log.error("产品激活错误!");
            throw new BusinessException(e.getMessage());
        }
        return logVO;
    }

    @Override
    public ProductActiveLogVO saveProductAdd(ActiveInfoVO[] infos) throws BusinessException {
        ProductActiveLogVO logVO = extractProductActiveLogVO(infos);
        BuziOrderInfoVO[] buziInfos = new BuziOrderInfoVO[infos.length];
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < infos.length; i++) {
            buziInfos[i] = new BuziOrderInfoVO();
            buziInfos[i].setPkTenant(infos[i].getKaiInstanceId());
            buziInfos[i].setAccountQuantity(infos[i].getAccountQuantity());
            buziInfos[i].setLease(infos[i].getLease());
            buziInfos[i].setOrderCId(infos[i].getOrderCId());
            buziInfos[i].setProductId(infos[i].getProductId());
            buziInfos[i].setSkuId(infos[i].getSkuId());
            buziInfos[i].setChangeFlag(UUID.randomUUID().toString());
            try {
                buziInfos[i].setActiveDate(formatter.parse(infos[i].getStart_time()));
            } catch (ParseException e) {
                buziInfos[i].setActiveDate(null);
            }
            buziInfos[i].setPurType((byte) 1);
        }
        buziOrderInfoMapper.batchInsert(Arrays.asList(buziInfos));
        // TODO 暂时没有加购后续操作
        return logVO;
    }

    @Override
    public ProductActiveLogVO saveProductRenew(ActiveInfoVO[] infos) throws BusinessException {
        ProductActiveLogVO logVO = extractProductActiveLogVO(infos);
        BuziOrderInfoVO[] buziInfos = new BuziOrderInfoVO[infos.length];
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (int i = 0; i < infos.length; i++) {
            buziInfos[i] = new BuziOrderInfoVO();
            buziInfos[i].setPkTenant(infos[i].getKaiInstanceId());
            buziInfos[i].setAccountQuantity(infos[i].getAccountQuantity());
            buziInfos[i].setLease(infos[i].getLease());
            buziInfos[i].setOrderCId(infos[i].getOrderCId());
            buziInfos[i].setProductId(infos[i].getProductId());
            buziInfos[i].setSkuId(infos[i].getSkuId());
            buziInfos[i].setChangeFlag(UUID.randomUUID().toString());
            try {
                buziInfos[i].setActiveDate(formatter.parse(infos[i].getStart_time()));
            } catch (ParseException e) {
                buziInfos[i].setActiveDate(null);
            }
            buziInfos[i].setPurType((byte) 2);
        }
        buziOrderInfoMapper.batchInsert(Arrays.asList(buziInfos));
        // TODO 暂时没有续购后续操作
        return logVO;
    }

    private ProductActiveLogVO extractProductActiveLogVO(ActiveInfoVO[] infos) throws ConcurrentOperationException {
        boolean lock = AutoReleaseLockUtil.addAutoReleaseLock(infos[0].getOrderId());
        if (!lock) {
            throw new ConcurrentOperationException("激活正在处理中，请稍后");
        }
        ProductActiveLogVO logVO = new ProductActiveLogVO();
        logVO.setActiveId(infos[0].getOrderId());
        logVO.setStep(1);
        logVO.setActiveDate(new Date(System.currentTimeMillis()));
        logVO.setChangeFlag(UUID.randomUUID().toString());
        try {
            logVO.setLogContent(mapper.writeValueAsString(infos));
        } catch (JsonProcessingException e) {
            log.error("订单信息序列化错误", e);
        }
        activeMapper.insert(logVO);
        return logVO;
    }


    @Override
    public ProductActiveLogVO queryLogByID(String activeID) throws BusinessException {
        ProductActiveLogVO[] origLogs = activeMapper.getByActiveId(activeID);
        if (ArrayUtils.isEmpty(origLogs)) {
            return null;
        } else {
            return origLogs[0];
        }
    }

    @Override
    public BuziOrderInfoVO insertOrderInfo(BuziOrderInfoVO buziInfo) throws BusinessException {
        buziOrderInfoMapper.insert(buziInfo);
        return buziInfo;
    }

    @Override
    public void insertScriptAndPrint(String tenantId, String sysId) throws BusinessException {
        ScriptProcess process = new ScriptProcess(properties);
        process.executeScript(tenantId, sysId);
        //初始化一套业务对象和打印模版
        PrintInitProcess printInitProcess = new PrintInitProcess(tenantId);
        printInitProcess.initTenantBizz();
    }

    @Override
    public void updateStep(ProductActiveLogVO logVO) throws BusinessException {
        ProductActiveLogVO[] origLogs = activeMapper.getByActiveId(logVO.getActiveId());
        ProductActiveLogVO origLog;
        boolean needInsert = false;
        if (ArrayUtils.isEmpty(origLogs)) {
            origLog = logVO;
            needInsert = true;
        } else {
            origLog = origLogs[0];
        }
        origLog.setFailedStep(logVO.getFailedStep());
        origLog.setStep(logVO.getStep());
        if (needInsert) {
            origLog.setChangeFlag(UUID.randomUUID().toString());
            activeMapper.insert(origLog);
        } else {
            activeMapper.updateFields(origLog, new String[]{"step", "failedStep"});
        }
    }

}
